package com.example.monitoring.controller;

import com.example.monitoring.config.MonitoringProperties;
import com.example.monitoring.model.MonitoringResult;
import com.example.monitoring.service.MonitoringService;
import com.example.monitoring.service.impl.MonitoringServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;

/**
 * 监控控制器类
 * 
 * @author rsz
 * @since 2024-04-13
 */
@Slf4j
@Controller
@RequestMapping("/")
public class MonitoringController {

    private final MonitoringService monitoringService;
    private final MonitoringProperties properties;

    @Autowired
    public MonitoringController(MonitoringService monitoringService, MonitoringProperties properties) {
        this.monitoringService = monitoringService;
        this.properties = properties;
    }

    /**
     * 监控仪表盘页面
     */
    @GetMapping
    public String dashboard(Model model) {
        log.debug("访问监控仪表盘页面");
        model.addAttribute("pageTitle", "监控仪表盘");
        return "dashboard";
    }
    
    /**
     * 获取所有监控结果数据
     */
    @GetMapping("/api/monitoring/results")
    @ResponseBody
    public ResponseEntity<List<MonitoringResult>> getMonitoringResults() {
        log.debug("获取所有监控结果数据");
        return ResponseEntity.ok(monitoringService.getAllMonitoringResults());
    }
    
    /**
     * 检查所有目标服务的健康状态
     */
    @GetMapping("/api/monitoring/check-all-target-services")
    @ResponseBody
    public ResponseEntity<List<Boolean>> checkAllTargetServicesHealth() {
        log.debug("手动检查所有目标服务健康状态");
        return ResponseEntity.ok(monitoringService.checkAllTargetServicesHealth());
    }
    
    /**
     * 检查单个目标服务健康状态
     */
    @GetMapping("/api/monitoring/check-target-service/{index}")
    @ResponseBody
    public ResponseEntity<Boolean> checkTargetServiceHealth(@PathVariable int index) {
        log.debug("手动检查目标服务健康状态, 索引: {}", index);
        return ResponseEntity.ok(monitoringService.checkTargetServiceHealth(index));
    }
    
    /**
     * 检查目标服务健康状态 (兼容旧接口)
     */
    @GetMapping("/api/monitoring/check-target-service")
    @ResponseBody
    public ResponseEntity<Boolean> checkTargetServiceHealth() {
        log.debug("手动检查目标服务健康状态 (兼容旧接口)");
        // 返回第一个目标服务的状态，保持向后兼容
        List<Boolean> results = monitoringService.checkAllTargetServicesHealth();
        return ResponseEntity.ok(!results.isEmpty() && results.get(0));
    }
    
    /**
     * 手动触发中间件监控 - 强制刷新缓存获取最新数据
     */
    @PostMapping("/api/monitoring/middleware/{name}")
    @ResponseBody
    public ResponseEntity<MonitoringResult> monitorMiddleware(@PathVariable String name) {
        log.info("手动触发中间件监控 (强制刷新): {}", name);
        
        try {
            // 调用强制刷新方法，清除缓存并获取最新数据
            MonitoringResult result = ((MonitoringServiceImpl) monitoringService).forceRefreshMonitoring(name);
            
            if (result == null) {
                log.warn("不支持的中间件类型: {}", name);
                return ResponseEntity.badRequest().build();
        }
        
        log.info("中间件 {} 监控完成，状态: {}", name, result.getStatus());
        return ResponseEntity.ok(result);
            
        } catch (Exception e) {
            log.error("中间件 {} 监控失败", name, e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 手动检查网络连通性
     */
    @PostMapping("/api/monitoring/network")
    @ResponseBody
    public ResponseEntity<List<MonitoringResult>> checkNetworkConnectivity() {
        log.debug("手动检查网络连通性");
        return ResponseEntity.ok(monitoringService.checkNetworkConnectivity());
    }
    
    /**
     * 获取中间件配置状态
     */
    @GetMapping("/api/monitoring/middleware/status")
    @ResponseBody
    public ResponseEntity<Object> getMiddlewareStatus() {
        log.debug("获取中间件配置状态");
        
        return ResponseEntity.ok(monitoringService.getMiddlewareConfigStatus());
    }
    
    /**
     * 导出监控报告
     */
    @PostMapping("/api/monitoring/export-report")
    @ResponseBody
    public ResponseEntity<String> exportReport() {
        log.debug("手动导出监控报告");
        String reportPath = monitoringService.exportReport();
        if (reportPath == null) {
            return ResponseEntity.internalServerError().body("导出报告失败");
        }
        return ResponseEntity.ok(reportPath);
    }
    
    /**
     * 报告页面
     */
    @GetMapping("/reports")
    public String reports(Model model) {
        log.debug("访问报告页面");
        model.addAttribute("pageTitle", "监控报告");
        return "report-template";
    }
    
    /**
     * 查看监控报告
     */
    @GetMapping("/monitoring/reports/view")
    public String viewReport(@RequestParam String filename, Model model) {
        log.debug("查看监控报告: {}", filename);
        
        try {
            String exportPath = properties.getReport().getExportPath();
            File reportFile = new File(exportPath, filename);
            
            if (!reportFile.exists()) {
                log.error("报告文件不存在: {}", reportFile.getAbsolutePath());
                model.addAttribute("error", "报告文件不存在");
                return "error";
            }
            
            String content = new String(Files.readAllBytes(reportFile.toPath()), StandardCharsets.UTF_8);
            model.addAttribute("reportContent", content);
            return "report-view";
        } catch (Exception e) {
            log.error("读取报告文件失败", e);
            model.addAttribute("error", "读取报告文件失败: " + e.getMessage());
            return "error";
        }
    }
    
    /**
     * 下载监控报告
     */
    @GetMapping("/monitoring/reports/download")
    public ResponseEntity<Resource> downloadReport(@RequestParam String filename) {
        log.debug("下载监控报告: {}", filename);
        
        try {
            String exportPath = properties.getReport().getExportPath();
            File reportFile = new File(exportPath, filename);
            
            if (!reportFile.exists()) {
                log.error("报告文件不存在: {}", reportFile.getAbsolutePath());
                return ResponseEntity.notFound().build();
            }
            
            InputStreamResource resource = new InputStreamResource(new FileInputStream(reportFile));
            
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                    .contentLength(reportFile.length())
                    .contentType(MediaType.TEXT_HTML)
                    .body(resource);
        } catch (Exception e) {
            log.error("下载报告文件失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }
} 